home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Amiga-E / E_v3.2a / Src / Utils / ShowHunk.e < prev    next >
Text File  |  1992-09-02  |  25KB  |  863 lines

  1. /* simple hunk-dump program with 680x0 disassembler for code hunks */
  2.  
  3. /*
  4.    WARNING: hunk_reloc32_short and hunk_relative_reloc hunks have not been
  5.    tested. If you find a file with this type of hunk, and this program
  6.    doesn't work with it, *PLEASE* contact the program authors so fixes may
  7.    be made.
  8. */
  9.  
  10. /* bugs left:
  11.    - link disasms wrong
  12.    - bset should give <illegal ea> with bit > 31
  13. */
  14.  
  15. OPT OSVERSION=37
  16.  
  17. ENUM HUNK_UNIT=$3E7, HUNK_NAME, HUNK_CODE, HUNK_DATA, HUNK_BSS, HUNK_RELOC32,
  18.      HUNK_RELOC16, HUNK_RELOC8, HUNK_EXT, HUNK_SYMBOL, HUNK_DEBUG,
  19.      HUNK_END, HUNK_HEADER, HUNK_OVERLAY=$3F5, HUNK_BREAK, HUNK_DRELOC32,
  20.      HUNK_DRELOC16, HUNK_DRELOC8, HUNK_LIB, HUNK_INDEX, HUNK_RELOC32_S,
  21.      HUNK_REL_RELOC32
  22.  
  23. ENUM EXT_SYM=0, EXT_DEF, EXT_ABS, EXT_RES, EXT_NEWCOMMON, EXT_REF32=129,
  24.      EXT_COMMON, EXT_REF16, EXT_REF8, EXT_DREF32, EXT_DREF16, EXT_DREF8
  25.  
  26. ENUM ER_NONE,ER_FILE,ER_MEM,ER_USAGE,ER_HUNKID,ER_BREAK,ER_FILETYPE
  27.  
  28. DEF flen,o:PTR TO LONG,mem,handle=NIL,hunkid,noreloc=TRUE,hunknr=-1,f=TRUE
  29. DEF pc:PTR TO INT,hibyte,eleven2nine,eight,seven2six,five2three,two2zero,isize
  30. DEF tmp,fname[256]:STRING,disasm
  31.  
  32. PROC main()
  33.   DEF options:PTR TO LONG,rdargs
  34.  
  35.   options:=[0,0]
  36.   IF rdargs:=ReadArgs('NAME/A,DISASM/S',options,NIL)
  37.     IF options[0] THEN StrCopy(fname,options[0])
  38.     disasm:=options[1]
  39.     FreeArgs(rdargs)
  40.   ELSE
  41.     error(ER_USAGE)
  42.   ENDIF
  43.  
  44.   PutStr('ShowHunk v2.0 Copyright (c) 1993 Jim Cooper\n')
  45.   PutStr(' Original ShowHunk v0.1 (c) 1992 $#%!\n\n')
  46.  
  47.   flen:=FileLength(fname)
  48.   handle:=Open(fname,OLDFILE)
  49.   IF (flen<1) OR (handle=NIL)
  50.     error(ER_FILE)
  51.   ELSE
  52.     mem:=New(flen)
  53.     IF mem=NIL
  54.       error(ER_MEM)
  55.     ELSE
  56.       IF Read(handle,mem,flen)<>flen THEN error(ER_FILE) ELSE process()
  57.     ENDIF
  58.   ENDIF
  59.   error(ER_NONE)
  60. ENDPROC
  61.  
  62. PROC process()
  63.   DEF end,type
  64.  
  65.   o:=mem
  66.   end:=o+flen
  67.   IF (o[]<>HUNK_HEADER) AND (o[]<>HUNK_UNIT) AND (o[]<>HUNK_LIB) THEN error(ER_FILETYPE)
  68.   PrintF('Hunk layout of file "\s" (\d bytes)\n\n',fname,flen)
  69.   WHILE o<end
  70.     IF CtrlC() THEN error(ER_BREAK)
  71.     type:=Int(o); hunkid:=Int(o+2); o:=o+4
  72.     IF (hunkid<>HUNK_UNIT) AND (hunkid<>HUNK_HEADER) AND (hunkid<>HUNK_BREAK) AND (hunkid<>HUNK_LIB) AND (hunkid<>HUNK_INDEX)
  73.       IF f
  74.         PrintF('HUNK \d',hunknr)
  75.         INC hunknr
  76.       ENDIF
  77.       f:=FALSE
  78.     ENDIF
  79.     IF type
  80.       IF type=$4000
  81.         PutStr('\t** hunk forced to CHIP-mem\n')
  82.       ELSE
  83.         PrintF('\t** type: \d\n',type)
  84.       ENDIF
  85.     ENDIF
  86.     SELECT hunkid
  87.       CASE HUNK_UNIT;        PutStr('\thunk_unit: '); name()
  88.       CASE HUNK_NAME;        PutStr('\thunk_name: '); name()
  89.       CASE HUNK_CODE;
  90.         PutStr('\thunk_code')
  91.         IF disasm
  92.           PutStr('\n'); code()
  93.         ELSE
  94.           PrintF(': \d bytes\n', skip())
  95.         ENDIF
  96.       CASE HUNK_DATA;        PrintF('\thunk_data: \d bytes\n',skip())
  97.       CASE HUNK_BSS;         PrintF('\thunk_bss: \d bytes\n',Mul(o[]++,4))
  98.       CASE HUNK_RELOC32;     PutStr('\thunk_reloc32\n'); reloc(4)
  99.       CASE HUNK_RELOC16;     PutStr('\thunk_reloc16\n'); reloc(4)
  100.       CASE HUNK_RELOC8;      PutStr('\thunk_reloc8\n'); reloc(4)
  101.       CASE HUNK_EXT;         PutStr('\thunk_ext\n'); symbol()
  102.       CASE HUNK_SYMBOL;      PutStr('\thunk_symbol\n'); symbol()
  103.       CASE HUNK_DEBUG;       PrintF('\thunk_debug: \d bytes\n',skip())
  104.       CASE HUNK_END;         f:=TRUE
  105.       CASE HUNK_HEADER;      PutStr('\thunk_header\n'); head()
  106.       CASE HUNK_OVERLAY;     PutStr('\thunk_overlay\n'); overlay()
  107.       CASE HUNK_BREAK;       PutStr('\thunk_break\n'); hunknr:=1; f:=TRUE
  108.       CASE HUNK_DRELOC32;    PutStr('\thunk_data-reloc32\n'); reloc(4)
  109.       CASE HUNK_DRELOC16;    PutStr('\thunk_data-reloc16\n'); reloc(4)
  110.       CASE HUNK_DRELOC8;     PutStr('\thunk_data-reloc8\n'); reloc(4)
  111.       CASE HUNK_LIB;         PrintF('\tlibrary_hunk: \d bytes\n',Mul(o[]++,4)); hunknr:=0
  112.       CASE HUNK_INDEX;       PrintF('\tlibrary_index: \d bytes\n\n',skip())
  113.       CASE HUNK_RELOC32_S;   PutStr('\thunk_reloc32_short\n'); reloc(2);
  114.       CASE HUNK_REL_RELOC32; PutStr('\thunk_relative_reloc32\n'); reloc(4);
  115.       DEFAULT
  116.         error(ER_HUNKID)
  117.     ENDSELECT
  118.   ENDWHILE
  119.   PutStr(IF noreloc THEN '\nPosition independant code!\n' ELSE '\n')
  120. ENDPROC
  121.  
  122. PROC overlay()
  123.   DEF m,ts
  124.   ts:=o[]++
  125.   PrintF('\t  tablesize = \d\n',ts)
  126.   m:=o[]++-2
  127.   PrintF('\t  max. level overlay tree uses = \d\n',m)
  128.   o:=ts*4+o
  129.   hunknr:=1; f:=TRUE
  130. ENDPROC
  131.  
  132. PROC symbol()
  133.   DEF t,l,s,c,r
  134.   t:=Char(o); l:=Int(o+2); o:=o+4
  135.   WHILE l
  136.     IF CtrlC() THEN error(ER_BREAK)
  137.     IF t<EXT_NEWCOMMON                  /* sym def */
  138.       s:=o; o:=l*4+o; c:=o[]++; PutChar(o-4,0)
  139.       PrintF('\t  \s = $\h\n',s,c)
  140.     ELSEIF t=EXT_COMMON OR t=EXT_NEWCOMMON  /* common ref */
  141.       s:=o; o:=l*4+o; c:=o[]++; PutChar(o-4,0); r:=o[]++
  142.       PrintF('\t  \s (\d ref\s) commonsize = \d\n',s,r,
  143.              IF r=1 THEN '' ELSE 's',c)
  144.       o:=r*4+o
  145.     ELSE                                /* sym ref */
  146.       s:=o; o:=l*4+o; r:=o[]++; PutChar(o-4,0)
  147.       PrintF('\t  \s (\d ref\s)\n',s,r,IF r=1 THEN '' ELSE 's')
  148.       o:=r*4+o
  149.     ENDIF
  150.     t:=Char(o); l:=Int(o+2); o:=o+4
  151.   ENDWHILE
  152. ENDPROC
  153.  
  154. PROC head()
  155.   DEF a,b
  156.   a:=0
  157.   b:=o[a]++
  158.   WHILE b
  159.     PrintF('\t  libname: \s\n',o)
  160.     a:=a+b
  161.     b:=o[a]++
  162.   ENDWHILE
  163.   b:=o[]++
  164.   hunknr:=o[]++
  165.   a:=o[]++-hunknr+1
  166.   PrintF('\t  #of hunks: \d\n',a)
  167.   o:=a*4+o
  168. ENDPROC
  169.  
  170. PROC reloc(size)
  171.   DEF a
  172.   noreloc:=FALSE
  173.   a:=o[]++
  174.   WHILE a
  175.     IF CtrlC() THEN error(ER_BREAK)
  176.     PrintF('\t  \d reloc entr\s for hunk #\d\n',a,
  177.            IF a=1 THEN 'y' ELSE 'ies',o[]++)
  178.     o:=a*size+o
  179.     a:=o[]++
  180.   ENDWHILE
  181. ENDPROC
  182.  
  183. PROC name()
  184.   DEF a
  185.   a:=o[]++
  186.   PrintF('\s\n',o)
  187.   o:=a*4+o
  188. ENDPROC
  189.  
  190. PROC skip()
  191.   DEF a
  192.   a:=Mul(o[]++,4)
  193.   o:=o+a
  194. ENDPROC a
  195.  
  196. PROC error(nr)
  197.   IF handle THEN Close(handle)
  198.   PutStr('\n')
  199.   SELECT nr
  200.     CASE ER_FILE;     PrintF('Could not read file "\s" !\n',fname)
  201.     CASE ER_MEM;      PutStr('No memory for hunks!\n')
  202.     CASE ER_USAGE;    PutStr('USAGE: ShowHunk <exe/objfile>\n')
  203.     CASE ER_HUNKID;   PrintF('Illegal hunk id: $\h !\n',hunkid)
  204.     CASE ER_BREAK;    PutStr('** BREAK: ShowHunk\n')
  205.     CASE ER_FILETYPE; PutStr('Not an executable or object file.\n')
  206.   ENDSELECT
  207.   CleanUp()
  208. ENDPROC
  209.  
  210. PROC illegal()
  211.   PrintF('<illegal opcode: $\h>\n',pc[])
  212. ENDPROC
  213.  
  214. PROC opsize(bit) RETURN ListItem(["b","w","l","?"],bit)
  215.  
  216. PROC bitsize(bit) RETURN IF bit THEN "l" ELSE "w"
  217.  
  218. PROC immed(val)
  219.   PrintF(IF val < 16 THEN '\d' ELSE '$\h',val)
  220. ENDPROC
  221.  
  222. PROC ccode(val,b) RETURN ListItem([IF b THEN 'ra' ELSE 't',
  223.   IF b THEN 'sr' ELSE 'f','hi','ls','cc','cs','ne','eq','vc',
  224.   'vs','pl','mi','ge','lt','gt','le','??'],val)
  225.  
  226. PROC ea(mode,reg,sd)
  227.   IF mode < 5 THEN
  228.     PrintF(ListItem(['d\d','a\d','(a\d)','(a\d)+','-(a\d)'],mode),reg)
  229.   SELECT mode
  230.     CASE 5;
  231.        PutStr('(')
  232.        immed(pc[1]++)
  233.        PrintF(',a\d)',reg)
  234.     CASE 6;
  235.       tmp:=pc[1]++
  236.       PutStr('(')
  237.       immed(tmp AND $f)
  238.       PrintF(',a\d,\s\d\s',reg,
  239.                            IF tmp AND $8000 THEN 'a' ELSE 'd',
  240.                            (Shr(tmp,12) AND 7),
  241.                            IF tmp AND $800 THEN '.L)' ELSE '.W)')
  242.     CASE 7;
  243.       SELECT reg
  244.         CASE 0;  PrintF('(\d).W',pc[1]++)
  245.         CASE 1;  immed(Long(pc+2)); pc:=pc+4      /* bug! was: immed(^pc++) */
  246.         CASE 2;
  247.           PutStr('(')
  248.           immed(pc[1]++)
  249.           PutStr(',PC)')
  250.         CASE 3;
  251.           tmp:=pc[1]++
  252.           PutStr('(')
  253.           immed(tmp AND $f)
  254.           PrintF(',PC,\c\d\s',IF tmp AND $8000 THEN "a" ELSE "d",
  255.                               (Shr(tmp,12) AND 7),
  256.                               IF tmp AND $800 THEN '.L)' ELSE '.W)')
  257.         CASE 4;
  258.           IF sd
  259.             PutStr('#')
  260.             immed(IF isize=2 THEN pc[1] ELSE Long(pc+2))
  261.             pc:=pc+isize
  262.           ELSE
  263.             PutStr('SR')
  264.           ENDIF
  265.         DEFAULT;
  266.           PutStr('<unknown ea!>')
  267.       ENDSELECT
  268.   ENDSELECT
  269. ENDPROC
  270.  
  271. PROC movemregs(val,predec)
  272.   DEF index,first=1,regs:PTR TO LONG
  273.  
  274.   regs:=['d0','d1','d2','d3','d4','d5','d6','d7',
  275.          'a0','a1','a2','a3','a4','a5','a6','a7']
  276.  
  277.   IF predec
  278.     FOR index:=15 TO 0 STEP -1
  279.       IF val AND Shl(1,index)
  280.         IF first = 0 THEN PutStr('/')
  281.         PutStr(regs[15-index])
  282.         first:=0
  283.       ENDIF
  284.     ENDFOR
  285.   ELSE
  286.     FOR index:=0 TO 15 STEP 1
  287.       IF val AND Shl(1,index)
  288.         IF first = 0 THEN PutStr('/')
  289.         PutStr(regs[index])
  290.         first:=0
  291.       ENDIF
  292.     ENDFOR
  293.   ENDIF
  294. ENDPROC
  295.  
  296. PROC code0000()
  297.   DEF c,tmp2
  298.  
  299.   IF (eleven2nine = 7) OR (seven2six = 3)
  300.     IF (eleven2nine = 7) AND (eight = 0)
  301.       tmp:=pc[1]++
  302.       PrintF('moves.\c\t',opsize(seven2six))
  303.       IF Shr(tmp,11) AND 1
  304.         ea(five2three,two2zero,1)
  305.         PrintF(',\c\d\n',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  306.       ELSE
  307.         PrintF('\c\d,',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  308.         ea(five2three,two2zero,0)
  309.         PutStr('\n')
  310.       ENDIF
  311.     ELSEIF (eight = 0) AND (seven2six = 3)
  312.       tmp:=pc[1]++
  313.       IF (five2three = 7) AND (two2zero = 4)
  314.         tmp2:=pc[1]++
  315.         PrintF('cas2\td\d:d\d,d\d:d\d,\c\d:\c\d\n',
  316.                (tmp AND 7), (tmp2 AND 7),
  317.                (Shr(tmp,6) AND 7), (Shr(tmp2,6) AND 7),
  318.                IF tmp AND $8000 THEN "a" ELSE "d", (Shr(tmp,12) AND 7),
  319.                IF tmp2 AND $8000 THEN "a" ELSE "d", (Shr(tmp2,12) AND 7))
  320.       ELSE
  321.         PrintF('cas\td\d,d\d,',tmp AND 7, Shr(tmp,6) AND 7)
  322.         ea(five2three,two2zero,0)
  323.         PutStr('\n')
  324.       ENDIF
  325.     ELSE
  326.       illegal()
  327.     ENDIF
  328.   ELSE
  329.     IF five2three = 1
  330.       PrintF('movep.\c\t',bitsize(seven2six AND 1))
  331.       IF seven2six AND 2
  332.         PrintF('d\d,\d(a\d)\n',eleven2nine,pc[1]++,two2zero)
  333.       ELSE
  334.         PrintF('\d(a\d),d\d\n',pc[1]++,two2zero,eleven2nine)
  335.       ENDIF
  336.     ELSEIF (eight = 1) OR ((((eleven2nine AND 3) = 0) AND (eight = 0)))
  337.       PrintF(ListItem(['btst\t','bchg\t','bclr\t','bset\t'],seven2six))
  338.       IF eight = 1
  339.         PrintF('d\d,',eleven2nine)
  340.       ELSE
  341.         PrintF('#\d,',pc[1]++)
  342.       ENDIF
  343.       ea(five2three,two2zero,0)
  344.       PutStr('\n')
  345.     ELSE
  346.       IF seven2six = 3
  347.         tmp:=pc[1]++
  348.         PrintF('\s.\c\t',IF Shr(tmp,11) AND 1 THEN 'chk2' ELSE 'cmp2',opsize(eleven2nine))
  349.         ea(five2three,two2zero,1)
  350.         PrintF(',\c\d\n',IF tmp AND $8000 THEN "d" ELSE "a",Shr(tmp,12) AND 3)
  351.       ELSE
  352.         c:=ListItem(['ori.','andi.','subi.','addi.',0,'eori.','cmpi.',0],eleven2nine)
  353.         IF c THEN PutStr(c) ELSE illegal()
  354.         PrintF('\c\t#',opsize(seven2six))
  355.         immed(IF seven2six < 2 THEN pc[1]++ ELSE ^pc++)
  356.         PutStr(',')
  357.         ea(five2three,two2zero,0)
  358.         PutStr('\n')
  359.       ENDIF
  360.     ENDIF
  361.   ENDIF
  362. ENDPROC
  363.  
  364. PROC code0100()
  365.   DEF subfield,bitseven,bitsix,curcode
  366.  
  367.   bitseven:=Shr(seven2six,1)
  368.   bitsix:=seven2six AND 1
  369.  
  370.   IF pc[] = $4afa
  371.     PutStr('bgnd\n')
  372.   ELSE
  373.     IF eight = 1
  374.       IF bitsix = 1
  375.         PutStr('lea\t')
  376.         ea(five2three,two2zero,1)
  377.         PrintF(',a\d\n',eleven2nine)
  378.       ELSE
  379.         PutStr('chk\t')
  380.         ea(five2three,two2zero,0)
  381.         PrintF(',d\d\n',eleven2nine)
  382.       ENDIF
  383.     ELSE
  384.       subfield:=Shl(eleven2nine,1)+eight
  385.  
  386.       SELECT subfield
  387.         CASE 0;
  388.           IF seven2six = 3
  389.             PutStr('move.w\t')
  390.             ea(five2three,two2zero,1)
  391.             PutStr(',sr\n')
  392.           ELSE
  393.             PrintF('negx.\c\t',opsize(seven2six))
  394.             ea(five2three,two2zero,0)
  395.             PutStr('\n')
  396.           ENDIF
  397.         CASE 1;
  398.           IF seven2six = 3
  399.             PutStr('move.w\tccr,')
  400.             ea(five2three,two2zero,0)
  401.             PutStr('\n')
  402.           ELSE
  403.             illegal()
  404.           ENDIF
  405.         CASE 2;
  406.           PrintF('clr.\c\t',opsize(seven2six))
  407.           ea(five2three,two2zero,0)
  408.           PutStr('\n')
  409.         CASE 4;
  410.           IF seven2six = 3
  411.             PutStr('move.w\t')
  412.             ea(five2three,two2zero,1)
  413.             PutStr(',ccr\n')
  414.           ELSE
  415.             PrintF('neg.\c\t',opsize(seven2six))
  416.             ea(five2three,two2zero,0)
  417.             PutStr('\n')
  418.           ENDIF
  419.         CASE 6;
  420.           IF seven2six = 3
  421.             PutStr('move.w\tsr,')
  422.             ea(five2three,two2zero,0)
  423.             PutStr('\n')
  424.           ELSE
  425.             PrintF('not.\c\t',opsize(seven2six))
  426.             ea(five2three,two2zero,0)
  427.             PutStr('\n')
  428.           ENDIF
  429.         CASE 8;
  430.           IF seven2six = 0
  431.             IF five2three = 1
  432.               PrintF('link.l\ta\d,#-$\h\n',two2zero,0-1-^pc++)
  433.             ELSE
  434.               PutStr('nbcd\t')
  435.               ea(five2three,two2zero,0)
  436.               PutStr('\n')
  437.             ENDIF
  438.           ELSEIF seven2six = 1
  439.             IF five2three = 0
  440.               PrintF('swap\td\d\n',two2zero)
  441.             ELSEIF five2three = 1
  442.               PrintF('bkpt\t#\d\n',two2zero)
  443.             ELSE
  444.               PutStr('pea\t')
  445.               ea(five2three,two2zero,0)
  446.               PutStr('\n')
  447.             ENDIF
  448.           ELSE
  449.             IF five2three = 0
  450.               IF (Shl(eight,2)+seven2six) = 7 THEN PrintF('extb.l\td\d\n',two2zero) ELSE PrintF('ext.\c\td\d\n',bitsize(bitsix),two2zero)
  451.             ELSE
  452.               PrintF('movem.\c\t',bitsize(bitsix))
  453.               movemregs(pc[1]++, IF five2three = 4 THEN 1 ELSE 0)
  454.               PutStr(',')
  455.               ea(five2three,two2zero,0)
  456.               PutStr('\n')
  457.             ENDIF
  458.           ENDIF
  459.         CASE 10;
  460.           IF pc[] = $4afc
  461.             PutStr('illegal\n')
  462.           ELSE
  463.             IF seven2six = 3
  464.               PutStr('tas\t')
  465.               ea(five2three,two2zero,0)
  466.               PutStr('\n')
  467.             ELSE
  468.               PrintF('tst.\c\t',opsize(seven2six))
  469.               ea(five2three,two2zero,0)
  470.               PutStr('\n')
  471.             ENDIF
  472.           ENDIF
  473.         CASE 12;
  474.           tmp:=pc[1]++
  475.  
  476.           IF (Shl(eight,2)+seven2six) < 2
  477.             IF seven2six = 1
  478.               PrintF('div\c',IF Shr(tmp,11) AND 1 THEN "s" ELSE "u")
  479.               IF ((Shr(tmp,10) AND 1) = 0) AND ((Shr(tmp,12) AND 7) <> (tmp AND 7))
  480.                 PutStr('l.l\t')
  481.                 ea(five2three,two2zero,1)
  482.                 PrintF(',d\d:d\d\n',Shr(tmp,12) AND 7,tmp AND 7)
  483.               ELSE
  484.                 PutStr('.l\t')
  485.                 ea(five2three,two2zero,1)
  486.                 PrintF(',d\d',Shr(tmp,12) AND 7)
  487.                 IF Shr(tmp,10) AND 1 THEN PrintF(':d\d',tmp AND 7)
  488.                 PutStr('\n')
  489.               ENDIF
  490.             ELSE
  491.               PrintF('mul\c.l\t',IF Shr(tmp,11) AND 1 THEN "s" ELSE "u")
  492.               ea(five2three,two2zero,1)
  493.               PrintF(',d\d',Shr(tmp,12) AND 7)
  494.               IF Shr(tmp,10) AND 1 THEN PrintF(':d\d',tmp AND 7)
  495.               PutStr('\n')
  496.             ENDIF
  497.           ELSE
  498.             PrintF('movem.\c\t',bitsize(bitsix))
  499.             ea(five2three,two2zero,0)
  500.             PutStr(',')
  501.             movemregs(tmp, IF five2three = 4 THEN 1 ELSE 0)
  502.             PutStr('\n')
  503.           ENDIF
  504.         CASE 14;
  505.           curcode:=pc[]
  506.  
  507.           SELECT curcode
  508.             CASE $4e70;
  509.               PutStr('reset\n')
  510.             CASE $4e71;
  511.               PutStr('nop\n')
  512.             CASE $4e72;
  513.               PutStr('stop\n')
  514.             CASE $4e73;
  515.               PutStr('rte\n')
  516.             CASE $4e74;
  517.               PrintF('rtd\t#\d\n',(Shl(pc[1]<32767+1,16)-pc[1]++))
  518.             CASE $4e75;
  519.               PutStr('rts\n')
  520.             CASE $4e76;
  521.               PutStr('trapv\n')
  522.             CASE $4e77;
  523.               PutStr('rtr\n')
  524.             DEFAULT;
  525.               IF bitseven = 1
  526.                 PutStr(IF bitsix = 1 THEN 'jmp\t' ELSE 'jsr\t')
  527.                 ea(five2three,two2zero,0)
  528.                 PutStr('\n')
  529.               ELSE
  530.                 IF bitsix = 1
  531.                   tmp:=Shr(five2three,1)
  532.  
  533.                   SELECT tmp
  534.                     CASE 0;
  535.                       PrintF('trap\t\d\n',(Shl((five2three AND 1),2)+two2zero))
  536.                     CASE 1;
  537.                       IF five2three AND 1
  538.                         PrintF('unlk\ta\d\n',two2zero)
  539.                       ELSE
  540.                         PrintF('link.w\ta\d,#-$\h\n',two2zero,65536-pc[1]); pc++
  541.  
  542.                       ENDIF
  543.                     CASE 2;
  544.                       PrintF(IF five2three AND 1 THEN 'move\tusp,a\d\n' ELSE 'move\ta\d,usp\n',two2zero)
  545.                     CASE 3;
  546.                       PrintF('rtm\t\c\d\n',IF five2three AND 1 THEN "a" ELSE "d",two2zero)
  547.                   ENDSELECT
  548.                 ELSE
  549.                   illegal()
  550.                 ENDIF
  551.               ENDIF
  552.           ENDSELECT
  553.         DEFAULT; illegal()
  554.       ENDSELECT
  555.     ENDIF
  556.   ENDIF
  557. ENDPROC
  558.  
  559. PROC code0101()
  560.   IF seven2six < 3
  561.     PutStr(IF eight = 1 THEN 'subq.' ELSE 'addq.')
  562.     PrintF('\c\t#\d,',opsize(seven2six),eleven2nine)
  563.     ea(five2three,two2zero,0)
  564.     PutStr('\n')
  565.   ELSE
  566.     IF five2three = 1
  567.       PrintF('db\s\td\d,L\z\h[8]\n',
  568.              ccode((Shl(eleven2nine,1)+eight),0),
  569.              two2zero,
  570.              pc-o-2-(Shl(pc[1]<32767+1,16)-pc[1]))
  571.       pc++
  572.     ELSEIF five2three = 7
  573.       PrintF('trap\s',ccode(Shl(eleven2nine,1)+eight,0))
  574.       IF two2zero < 4
  575.         IF two2zero AND 1 THEN PrintF('.w\t#\d',pc[1]++) ELSE PrintF('.l\t#\d',^pc++)
  576.       ENDIF
  577.       PutStr('\n')
  578.     ELSE
  579.       PrintF('s\s\t',ccode(Shl(eleven2nine,1)+eight,0))
  580.       ea(five2three,two2zero,0)
  581.       PutStr('\n')
  582.     ENDIF
  583.   ENDIF
  584. ENDPROC
  585.  
  586. PROC code0110()
  587.   DEF tmp2,ctl:PTR TO LONG
  588.  
  589.   IF (pc[] AND $fffe) = $4e7a
  590.     tmp:=pc[1]++
  591.     tmp2:= tmp AND $fff
  592.     IF tmp2 > 7
  593.       ctl:=ListItem(['usp','vbr','caar','msp','isp','mmusr','urp','srp'],tmp2 - $800)
  594.     ELSE
  595.       ctl:=ListItem(['sfc','dfc','cacr','tc','itt0','itt1','dtt0','dtt1'],tmp2)
  596.     ENDIF
  597.     IF ctl
  598.       PutStr('movec\t')
  599.       IF pc[-1] AND 1
  600.         PrintF('\s,\c\d\n',ctl,IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7)
  601.       ELSE
  602.         PrintF('\c\d,\s\n',IF tmp AND $8000 THEN "a" ELSE "d",Shr(tmp,12) AND 7,ctl)
  603.       ENDIF
  604.     ELSE
  605.       illegal()
  606.     ENDIF
  607.   ELSE
  608.     PrintF('b\s',ccode((Shl(eleven2nine,1)+eight),1))
  609.     tmp:=Char(pc+1)
  610.     IF tmp = 0
  611.       PrintF('.w\tL\z\h[8]\n',pc-o-2-(Shl(pc[1]<32767+1,16)-pc[1]))
  612.       pc++
  613.     ELSE
  614.       PrintF('.b\tL\z\h[8]\n',pc-o-2-(Shl(tmp<127+1,8)-tmp))
  615.     ENDIF
  616.   ENDIF
  617. ENDPROC
  618.  
  619. PROC code1000()
  620.   IF Shr(pc[],4) AND %11111 = %10100   /* bug!: was  Shr(five2three,1) = 0 */
  621.     IF eight
  622.       IF seven2six
  623.         SELECT seven2six
  624.           CASE 1;  PutStr('pack\t')
  625.           CASE 2;  PutStr('unpk\t')
  626.           DEFAULT; illegal()
  627.         ENDSELECT
  628.         PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d),#\d\n' ELSE 'd\d,d\d,#\d\n',two2zero,eleven2nine,pc[1]++)
  629.       ELSE
  630.         PrintF(IF five2three AND 1 THEN 'sbcd\t-(a\d),-(a\d)\n' ELSE 'sbcd\td\d,-d\d\n',two2zero,eleven2nine)
  631.       ENDIF
  632.     ELSE
  633.       illegal()
  634.     ENDIF
  635.   ELSE
  636.     IF seven2six = 3
  637.       PutStr(IF eight = 1 THEN 'divs\t' ELSE 'divu\t')
  638.       ea(five2three,two2zero,1)
  639.       PrintF(',d\d\n',eleven2nine)
  640.     ELSE
  641.       PrintF('or.\c\t',opsize(seven2six))
  642.       IF eight = 1
  643.         PrintF('d\d,',eleven2nine)
  644.         ea(five2three,two2zero,0)
  645.       ELSE
  646.         ea(five2three,two2zero,1)
  647.         PrintF(',d\d',eleven2nine)
  648.       ENDIF
  649.       PutStr('\n')
  650.     ENDIF
  651.   ENDIF
  652. ENDPROC
  653.  
  654. PROC code1001()
  655.   IF seven2six = 3
  656.     PrintF('suba.\c\t',bitsize(eight))
  657.     ea(five2three,two2zero,1)
  658.     PrintF(',a\d\n',eleven2nine)
  659.   ELSE
  660.     IF (Shr(five2three,1) = 0) AND (eight = 1)
  661.       PrintF('subx.\c\t',opsize(seven2six))
  662.       PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d)\n' ELSE 'd\d,d\d\n',two2zero,eleven2nine)
  663.     ELSE
  664.       PrintF('sub.\c\t',opsize(seven2six))
  665.       IF eight = 1
  666.         PrintF('d\d,',eleven2nine)
  667.         ea(five2three,two2zero,0)
  668.         PutStr('\n')
  669.       ELSE
  670.         ea(five2three,two2zero,1)
  671.         PrintF(',d\d\n',eleven2nine)
  672.       ENDIF
  673.     ENDIF
  674.   ENDIF
  675. ENDPROC
  676.  
  677. PROC code1011()
  678.   IF seven2six = 3
  679.     PrintF('cmpa.\c\t',bitsize(eight))
  680.     ea(five2three,two2zero,1)
  681.     PrintF(',a\d\n',eleven2nine)
  682.   ELSE
  683.     IF five2three = 1
  684.       PrintF('cmpm.\c\t(a\d)+,(a\d)+\n',opsize(seven2six),two2zero,eleven2nine)
  685.     ELSE
  686.       IF eight = 1
  687.         PrintF('eor.\c\td\d,',opsize(seven2six),eleven2nine)
  688.         ea(five2three,two2zero,0)
  689.         PutStr('\n')
  690.       ELSE
  691.         PrintF('cmp.\c\t',opsize(seven2six))
  692.         ea(five2three,two2zero,1)
  693.         PrintF(',d\d\n',eleven2nine)
  694.       ENDIF
  695.     ENDIF
  696.   ENDIF
  697. ENDPROC
  698.  
  699. PROC code1100()
  700.   IF seven2six = 3
  701.     PutStr(IF eight = 1 THEN 'mulu.w\t' ELSE 'muls.w\t')
  702.     ea(five2three,two2zero,1)
  703.     PrintF(',d\d\n',eleven2nine)
  704.   ELSE
  705.     IF Shr(five2three,1) <> 0
  706.       PrintF('and.\c\t',opsize(seven2six))
  707.       IF eight = 1
  708.         PrintF('d\d,',eleven2nine)
  709.         ea(five2three,two2zero,0)
  710.         PutStr('\n')
  711.       ELSE
  712.         ea(five2three,two2zero,1)
  713.         PrintF(',d\d\n',eleven2nine)
  714.       ENDIF
  715.     ELSE
  716.       IF seven2six = 0
  717.         PrintF(IF five2three AND 1 THEN 'abcd\t-(a\d),-(a\d)\n' ELSE 'abcd\td\d,d\d\n',two2zero,eleven2nine)
  718.       ELSE
  719.         PutStr('exg\t')
  720.         tmp:=Shl(seven2six,3)+five2three
  721.         IF tmp = 8
  722.           PrintF('d\d,d\d\n',two2zero,eleven2nine)
  723.         ELSEIF tmp = 9
  724.           PrintF('a\d,a\d\n',two2zero,eleven2nine)
  725.         ELSEIF tmp = 17
  726.           PrintF('a\d,d\d\n',two2zero,eleven2nine)
  727.         ELSE
  728.           illegal()
  729.         ENDIF
  730.       ENDIF
  731.     ENDIF
  732.   ENDIF
  733. ENDPROC
  734.  
  735. PROC code1101()
  736.   IF seven2six = 3
  737.     PrintF('adda.\c\t',bitsize(eight))
  738.     ea(five2three,two2zero,1)
  739.     PrintF(',a\d\n',eleven2nine)
  740.   ELSE
  741.     IF (Shr(five2three,1) = 0) AND (eight = 1)
  742.       PrintF('addx.\c\t',opsize(seven2six))
  743.       PrintF(IF five2three AND 1 THEN '-(a\d),-(a\d)\n' ELSE 'd\d,d\d\n',two2zero,eleven2nine)
  744.     ELSE
  745.       PrintF('add.\c\t',opsize(seven2six))
  746.       IF eight = 1
  747.         PrintF('d\d,',eleven2nine)
  748.         ea(five2three,two2zero,0)
  749.         PutStr('\n')
  750.       ELSE
  751.         ea(five2three,two2zero,1)
  752.         PrintF(',d\d\n',eleven2nine)
  753.       ENDIF
  754.     ENDIF
  755.   ENDIF
  756. ENDPROC
  757.  
  758. PROC code1110()
  759.   DEF subfield,tmp2
  760.  
  761.   IF seven2six = 3
  762.     tmp:=pc[1]++
  763.     tmp2:=tmp AND 31
  764.     subfield:=Shl((eleven2nine AND 3),1)+eight
  765.     PutStr(ListItem(['bftst','bfextu','bfchg','bfexts','bfclr','bfffo','bfset','bfins'],subfield))
  766.     PutStr('\t')
  767.     IF subfield = 7 THEN PrintF('d\d,',Shr(tmp,12) AND 7)
  768.     ea(five2three,two2zero,0)
  769.     PrintF(IF Shr(tmp,11) AND 1 THEN '{d\d:' ELSE '{\d:',Shr(tmp,6) AND 31)
  770.     PrintF(IF Shr(tmp,5) AND 1 THEN 'd\d}' ELSE '\d}',IF tmp2 THEN tmp2 ELSE 32)
  771.  
  772.     IF (subfield < 7) AND (subfield AND 1) THEN PrintF(',d\d',Shr(tmp,12) AND 7)
  773.  
  774.     PutStr('\n')
  775.   ELSE
  776.     PrintF('\s\c',ListItem(['as','ls','rox','ro'],IF seven2six=3 THEN eleven2nine ELSE five2three AND 3),IF eight=1 THEN "l" ELSE "r")
  777.     IF seven2six = 3
  778.       PutStr('\t')
  779.       ea(five2three,two2zero,0)
  780.       PutStr('\n')
  781.     ELSE
  782.       PrintF(IF five2three AND 4 THEN '.\c\td\d,d\d\n' ELSE '\c\t#\d,d\d\n',opsize(seven2six),eleven2nine,two2zero)
  783.     ENDIF
  784.   ENDIF
  785. ENDPROC
  786.  
  787. PROC code()
  788.   DEF number
  789.  
  790.   isize:=2
  791.   number:=Shl(o[],2)+o+4
  792.   pc:=o+4
  793.  
  794.   PutStr('\n')
  795.  
  796.   WHILE (pc < number)
  797.     hibyte:=Shr(Char(pc),4)
  798.     eleven2nine:=Shr(Char(pc),1) AND 7
  799.     eight:=Char(pc) AND 1
  800.     seven2six:=Shr(Char(pc+1),6) AND 3
  801.     five2three:=Shr(Char(pc+1),3) AND 7
  802.     two2zero:=Char(pc+1) AND 7
  803.  
  804.     IF CtrlC() THEN error(ER_BREAK)             /* essential! */
  805.  
  806.     PrintF('L\z\h[8]:',pc-o-4)                  /* for offsets */
  807.  
  808.     PutStr('\t')
  809.  
  810.     IF (hibyte > 0) AND (hibyte < 4)
  811.       PutStr(IF (eight=0) AND (seven2six=1) THEN 'movea.' ELSE 'move.')
  812.       SELECT hibyte
  813.         CASE 1; PutStr('b')
  814.         CASE 2; PutStr('l'); isize:=4
  815.         CASE 3; PutStr('w')
  816.       ENDSELECT
  817.       PutStr('\t')
  818.       ea(five2three,two2zero,1)
  819.       PutStr(',')
  820.       ea(Shl(eight,2)+seven2six,eleven2nine,0)
  821.       PutStr('\n')
  822.       isize:=2
  823.     ELSE
  824.       SELECT hibyte
  825.         CASE 0;                 /* Bit Manipulation/MOVEP/immediate */
  826.           code0000()
  827.         CASE 4;                 /* Miscellaneous */
  828.           code0100()
  829.         CASE 5;                 /* ADDQ/SUBQ/Scc/DBcc/TRAPcc */
  830.           code0101()
  831.         CASE 6;                 /* Bcc/BSR/BRA/MOVEC */
  832.           code0110()
  833.         CASE 7;                 /* MOVEQ */
  834.           PutStr('moveq\t#')
  835.           immed(Char(pc+1))
  836.           PrintF(',d\d\n',eleven2nine)
  837.         CASE 8;                 /* OR/DIV/SBCD */
  838.           code1000()
  839.         CASE 9;                 /* SUB/SUBA/SUBX */
  840.           code1001()
  841.         CASE 10;                /* (unassigned, reserved) */
  842.           illegal()
  843.         CASE 11;                /* CMP/EOR */
  844.           code1011()
  845.         CASE 12;                /* AND/MUL/ABCD/EXG */
  846.           code1100()
  847.         CASE 13;                /* ADD/ADDX */
  848.           code1101()
  849.         CASE 14;                /* Shift/Rotate/Bit Field */
  850.           code1110()
  851.         CASE 15;                /* Coprocessor Interface */
  852.           illegal()
  853.       ENDSELECT
  854.     ENDIF
  855.     pc++
  856.   ENDWHILE
  857.  
  858.   PutStr('\n')
  859.  
  860.   o:=number
  861. ENDPROC
  862.  
  863.